#include "SearchEngineServer.h"
#include "TcpConnection.h"
#include "Dictionary.h"
#include "KeyRecommander.h"
#include "WebPageSearcher.h"
#include "WebPageQuery.h"
#include "SplitToolCppJieba.h"
#include "CacheManager.h"
#include "Configuration.h"
#include "json.hpp"
#include <iostream>
#include <functional>
using std::cout;
using std::endl;
using std::bind;

extern thread_local int thread_id;

MyTask::MyTask(const string &msg, int id, const TcpConnectionPtr &con)
: _msg(msg)
, _id(id)
, _con(con){

}

void MyTask::process(){
    //处理业务逻辑
    cout << "线程ID: " << thread_id << "\n";
    cout << "消息ID: " << _id << "\n";
    cout << "查询内容: " << _msg << "\n";

    //获取配置文件类的单例对象
    Configuration *config = Configuration::getInstance("../conf/myconf.conf");
    //获取缓存管理类的单例对象
    CacheManager *instance = CacheManager::getInstance();
    
    if(_id == 1){
        //处理候选词推荐任务
        string result;
        {
            lock_guard<mutex> lock(instance->getMutex(thread_id));
            result = instance->getCache(thread_id).getElement(_msg);
            //从缓存中读出的一定是json转换成的string，可以直接发送
        }
        if(result.size()){
            _con->sendInLoop(result, 1);
            cout << "读取缓存成功\n";
            return;
        }
        Dictionary *dict = Dictionary::createInstance();
        dict->init(config->parseConfig("DICT_DIR"));
        KeyRecommander key(_msg, _con, dict);
        key.execute(thread_id);
    }
    else{
        //处理网页搜索任务
        SplitToolCppJieba jieba(config); 
        WebPageQuery query(config, jieba);
        WebPageSearcher web(_msg, _con, query);
        web.doQuery();
    }
}

SearchEngineServer::SearchEngineServer(size_t threadNum, size_t queSize
                       , const string &ip
                       , unsigned short port)
: _pool(threadNum, queSize)
, _server(ip, port){

}

SearchEngineServer::~SearchEngineServer(){

}

//让服务器启动与停止
void SearchEngineServer::start(){
    _pool.start();
    using namespace  std::placeholders;
    _server.setAllCallback(bind(&SearchEngineServer::onNewConnection, this, _1)
                           , bind(&SearchEngineServer::onMessage, this, _1)
                           , bind(&SearchEngineServer::onClose, this, _1));
    _server.start();
}

void SearchEngineServer::stop(){
    _pool.stop();
    _server.stop();
}

//三个回调函数
void SearchEngineServer::onNewConnection(const TcpConnectionPtr &con){
    cout << con->toString() << " has connected!!!" << endl;
}

void SearchEngineServer::onMessage(const TcpConnectionPtr &con){
    pair<string, int> msg = con->receive();
    //
    MyTask task(msg.first, msg.second, con);
    _pool.addTask(bind(&MyTask::process, task));
}

void SearchEngineServer::onClose(const TcpConnectionPtr &con){
    cout << con->toString() << " has closed!!!" << endl;
}
